﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace SarjetLib
{
  public class CmdAnalysisArgs_t
  {
    public static readonly string HelperString = $@"
软件名称:
  MediaMetadataTagEditor_cmd

软件版本:
  v1.0.0

软件功能:
  可以提取文件名的信息, 设置媒体文件的TagInfo相关信息

命令行说明:
  -dir               / d     : 目录下的文件
    -rfilter         / r     : 正则过滤器

  -file              / f     : 接收的文件

  -debug             / dbg   : 调试模式
  -pause             / p     : 退出前暂停

  -regexName         / rn    : 正则名称
  -Title             / bt    : 标题
  -Subtitle          / fbt   : 副标题
  -Category          / bj    : 标记
  -Comment           / bz    : 备注
  -Artist            / ysj   : 参与创作的艺术家
  -ContentCreateDate / n     : 年
  -Genre             / lp    : 流派
  -Director          / dy    : 导演
  -Producer          / zzr   : 制作人
  -Writer            / czr   : 创作人
  -Publisher         / fbz   : 发布者
  -EncodedBy         / bmry  : 编码人员
  -AuthorURL         / zzurl : 作者URL
  -PromotionURL      / cxurl : 促销URL
  -ParentalRating    / jzfj  : 家长分级
  -Composer          / zqz   : 作曲者
  -Conductor         / zhz   : 指挥者
  -Period            / sq    : 时期
  -Mood              / fw    : 氛围
  -DiskNumber        / bfsz  : 部分设置
  -InitialKey        / cstx  : 初始调性
  -BeatsPerMinute    / jps   : 每分钟节拍数

示例:
1. 修改 L123.mp4 的Tag标题为L123(文件名), -dbg 表示打印参数不操作
  MediaMetadataTagEditor_cmd.exe -f ""L123.mp4"" -regexName ""(?<name>.+)\.mp4$"" -Title ""$name$"" -dbg -p

2. 遍历 ./ (当前文件夹下包含子文件夹的) *.mp4 的Tag标题并修改为文件名, -dbg 表示打印参数不操作
  MediaMetadataTagEditor_cmd.exe -d ""./"" -r "".+\.(mp4)$"" -regexName ""(?<name>.+)\.mp4$"" -Title ""$name$"" -dbg -p
";

    public List<MetaInfo_t> aMetaInfo = new List<MetaInfo_t>();
    public string dir = "";
    public string rfilter = "";
    public string file = "";
    public string regexName = @"[\s\S]+";
    public bool isDebug = false;
    public bool exitPause = false;
    public const int nWidth = -6;

    public override string ToString()
    {
      StringBuilder sb = new StringBuilder();
      sb.AppendLine($"path: {file}");
      return sb.ToString();
    }

    static readonly string sarg = @"" +
      @"(?:-(?<file>(?:file|f)\b))" +
      @"|(?:-(?<dir>(?:dir|d)\b))" +
      @"|(?:-(?<rfilter>(?:rfilter|r)\b))" +
      @"|(?:-(?<debug>(?:debug|dbg)\b))" +
      @"|(?:-(?<pause>(?:pause|p)\b))" +
      @"|(?:-(?<regexName>(?:regexName|rn)\b))" +                // 正则名称
      @"|(?:-(?<Title>(?:Title|bt)\b))" +                        // 标题
      @"|(?:-(?<Subtitle>(?:Subtitle|fbt)\b))" +                 // 副标题
      @"|(?:-(?<Category>(?:Category|bj)\b))" +                  // 标记
      @"|(?:-(?<Comment>(?:Comment|bz)\b))" +                    // 备注
      @"|(?:-(?<Artist>(?:Artist|ysj)\b))" +                     // 参与创作的艺术家
      @"|(?:-(?<ContentCreateDate>(?:ContentCreateDate|n)\b))" + // 年
      @"|(?:-(?<Genre>(?:Genre|lp)\b))" +                        // 流派
      @"|(?:-(?<Director>(?:Director|dy)\b))" +                  // 导演
      @"|(?:-(?<Producer>(?:Producer|zzr)\b))" +                 // 制作人
      @"|(?:-(?<Writer>(?:Writer|czr)\b))" +                     // 创作人
      @"|(?:-(?<Publisher>(?:Publisher|fbz)\b))" +               // 发布者
      @"|(?:-(?<EncodedBy>(?:EncodedBy|bmry)\b))" +              // 编码人员
      @"|(?:-(?<AuthorURL>(?:AuthorURL|zzurl)\b))" +             // 作者URL
      @"|(?:-(?<PromotionURL>(?:PromotionURL|cxurl)\b))" +       // 促销URL
      @"|(?:-(?<ParentalRating>(?:ParentalRating|jzfj)\b))" +    // 家长分级
      @"|(?:-(?<Composer>(?:Composer|zqz)\b))" +                 // 作曲者
      @"|(?:-(?<Conductor>(?:Conductor|zhz)\b))" +               // 指挥者
      @"|(?:-(?<Period>(?:Period|sq)\b))" +                      // 时期
      @"|(?:-(?<Mood>(?:Mood|fw)\b))" +                          // 氛围
      @"|(?:-(?<DiskNumber>(?:DiskNumber|bfsz)\b))" +            // 部分设置
      @"|(?:-(?<InitialKey>(?:InitialKey|cstx)\b))" +            // 初始调性
      @"|(?:-(?<BeatsPerMinute>(?:BeatsPerMinute|jps)\b))" +     // 每分钟节拍数
      @"";
    static Regex rarg = new Regex(sarg, RegexOptions.Compiled | RegexOptions.IgnoreCase);

    public void Analysis(string[] args)
    {
      for (int i = 0; i < args.Length; i++)
      {
        string arg = args[i];
        var m = rarg.Match(arg);
        if (m.Success)
        {
          if (m.Groups["file"].Success) file = args[++i];
          else if (m.Groups["dir"].Success) dir = args[++i];
          else if (m.Groups["rfilter"].Success) rfilter = args[++i];
          else if (m.Groups["debug"].Success) isDebug = true;
          else if (m.Groups["pause"].Success) exitPause = true;
          else if (m.Groups["regexName"].Success) regexName = args[++i];
          else if (m.Groups["Title"].Success) { var v = Metadata_t.dtMeta["Title"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["Subtitle"].Success) { var v = Metadata_t.dtMeta["Subtitle"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["Category"].Success) { var v = Metadata_t.dtMeta["Category"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["Comment"].Success) { var v = Metadata_t.dtMeta["Comment"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["Artist"].Success) { var v = Metadata_t.dtMeta["Artist"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["ContentCreateDate"].Success) { var v = Metadata_t.dtMeta["ContentCreateDate"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["Genre"].Success) { var v = Metadata_t.dtMeta["Genre"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["Director"].Success) { var v = Metadata_t.dtMeta["Director"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["Producer"].Success) { var v = Metadata_t.dtMeta["Producer"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["Writer"].Success) { var v = Metadata_t.dtMeta["Writer"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["Publisher"].Success) { var v = Metadata_t.dtMeta["Publisher"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["EncodedBy"].Success) { var v = Metadata_t.dtMeta["EncodedBy"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["AuthorURL"].Success) { var v = Metadata_t.dtMeta["AuthorURL"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["PromotionURL"].Success) { var v = Metadata_t.dtMeta["PromotionURL"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["ParentalRating"].Success) { var v = Metadata_t.dtMeta["ParentalRating"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["Composer"].Success) { var v = Metadata_t.dtMeta["Composer"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["Conductor"].Success) { var v = Metadata_t.dtMeta["Conductor"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["Period"].Success) { var v = Metadata_t.dtMeta["Period"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["Mood"].Success) { var v = Metadata_t.dtMeta["Mood"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["DiskNumber"].Success) { var v = Metadata_t.dtMeta["DiskNumber"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["InitialKey"].Success) { var v = Metadata_t.dtMeta["InitialKey"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
          else if (m.Groups["BeatsPerMinute"].Success) { var v = Metadata_t.dtMeta["BeatsPerMinute"]; v.regexGroupName = args[++i]; aMetaInfo.Add(v); }
        }
      }
    }

    public int Check_i(List<string> argadd, string[] args, ref int k, int maxk)
    {
      int cnt = 0;
      while (++k < maxk)
      {
        if (!string.IsNullOrEmpty(args[k]))
        {
          var tk = args[k].TrimStart();
          if (tk.StartsWith("-"))
          {
            k--;
            break;
          }
          cnt++;
          argadd.Add(args[k]);
        }
      }
      return cnt;
    }


    private static string ConvertRelPath(string path)
    {
      Uri cur = new Uri(Environment.CurrentDirectory + "\\");
      Uri rel = new Uri(path, UriKind.Relative);
      Uri cnv = new Uri(cur, rel);
      path = cnv.LocalPath;
      Console.WriteLine();
      Console.WriteLine($"Relpath convert:");
      Console.WriteLine($"{"Cur",nWidth}: {cur.LocalPath}");
      Console.WriteLine($"{"Rel",nWidth}: {rel}");
      Console.WriteLine($"{"Cnv",nWidth}: {cnv.LocalPath}");
      return path;
    }

    public bool FileisExist()
    {
      //转换相对路径
      if (file.Length > 2 && file[1] != ':')
      {
        file = ConvertRelPath(file);
      }
      if (!File.Exists(file))
      {
        //Console.WriteLine($"File not exist.");
        return false;
      }
      return true;
    }

    public bool DirisExist()
    {
      //转换相对路径
      if (dir.Length >= 2 && dir[1] != ':')
      {
        dir = ConvertRelPath(dir);
      }
      if (!Directory.Exists(dir))
      {
        //Console.WriteLine($"Path not exist.");
        return false;
      }
      return true;
    }

    public bool CheckRelPath()
    {
      if(!FileisExist())
      {
        if (!DirisExist())
        {
          return false;
        }
      }
      return true;
    }
  }
}
